package com.animerank.interceptor;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import com.animerank.utils.UserContextHolder;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;

/**
 * 登录拦截器
 * 用于检查用户是否登录，并将用户ID放入ThreadLocal中
 */
@Component
@Log4j2
public class LoginInterceptor implements HandlerInterceptor {

    // 从配置文件中读取不需要登录的路径
    @Value("${anime-rank.no-auth-paths:/swagger-ui.html,/swagger-ui/**,/v3/api-docs/**,/api/user/login,/api/user/register,/api/anime/search,/api/anime/rank/monthly,/api/vote/count/**,/api/douban/search,/api/douban/image-proxy}")
    private String[] noAuthPaths;

    // 路径匹配器，用于匹配URL路径
    private AntPathMatcher pathMatcher = new AntPathMatcher();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestPath = request.getRequestURI();

        // 检查当前请求是否在不需要登录的路径列表中
        for (String path : noAuthPaths) {
            if (pathMatcher.match(path, requestPath)) {
                return true; // 不需要登录，直接放行
            }
        }

        // 需要登录的请求，检查用户是否已登录
        try {
            // 检查是否登录，未登录会抛出NotLoginException异常
            StpUtil.checkLogin();

            // 登录成功，获取用户ID并放入ThreadLocal
            Object userId = StpUtil.getLoginId();
            UserContextHolder.setUserId(userId.toString());
            log.debug("用户[{}]登录成功，请求路径：{}", userId, requestPath);
            return true;
        } catch (NotLoginException e) {
            // 未登录或登录过期
            log.debug("用户未登录或登录已过期，请求路径：{}", requestPath);
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write("{\"code\": 401, \"msg\": \"未登录或登录已过期\"}");
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 请求处理完成后，清除ThreadLocal中的用户ID，防止内存泄漏
        UserContextHolder.clear();
    }
}